<?php

class filecache{
    private $cache_path = null;

    public function __construct()
    {
        $this->cache_path = APPLICATION_DIR.'../data/cache/';
    }

    /**
     * 写入缓存
     * @param $key   缓存的key
     * @param $val   数值
     * @param int $ttl 缓存时间多少秒
     * @return int
     */
    public function set($key, $val, $ttl=0){
        $time = $ttl==0 ? 0 : (time() + $ttl);
        $hash = md5($key);
        $file = $this->get_cache_file($key);
        $data = is_array($val) ? var_export($val, true) : "'{$val}'";
        $tmpl = '<?php
/**
 * note:System cache file, DO NOT modify me!
 * hash:{hash}:{key};
 * time:{time}
 */
if({time}===0 || time()<{time}){return {data};}return false;';
        $content = str_replace(array('{hash}', '{key}','{data}','{time}'), array($hash, $key,$data,$time), $tmpl);
        //file_put_contents该函数将返回写入到文件内数据的字节数
        return file_put_contents($file, $content);
    }

    /**
     * 获取缓存
     * @param $key
     * @return bool|mixed
     */
    public function get($key)
    {
        $file = $this->get_cache_file($key);
        if(is_file($file)){
            return @include($file);
        }
        return false;
    }

    /**
     * 获取文件缓存的完整物理路径
     * @param $key
     * @return string
     */
    protected function get_cache_file($key)
    {
        $hash = md5($key);
        $sub_dir = strtolower(substr($key,0,3));
        if(!is_dir($this->cache_path.$sub_dir)){
            mkdir($this->cache_path.$sub_dir);
        }
        return $this->cache_path.$sub_dir.'/'.$key.'@'.$hash.'.php';
    }

    /**
     * 删除文件缓存
     * @param $key
     */
    public function delete($key)
    {
        @unlink($this->get_cache_file($key));
    }

    /**
     * 清除所有的缓存
     * @return bool
     */
    public function clean($opendir='')
    {
        $dir = !$opendir ?  $this->cache_path : $opendir;
        if(!$handler = opendir($dir)){
            return false;
        }
        while(false !== ($file = readdir($handler))){
            if($file == '.' || $file == '..') {
                continue;
            }
            if(is_file($dir.$file)){
                @unlink($dir.$file);
            }elseif(is_dir($dir.$file)){
                $this->clean($dir.$file.'/');
            }
        }
        closedir($handler);
        return true;
    }

}